// <copyright file="LayoutManager.cs" company="YUIAsp.Net">
// Copyright (c) 2009 All Right Reserved
// </copyright>
// <author>raul popescu</author>
// <email>dev@yuiasp.net</email>
// <date>2009-01-30</date>
// <summary>YUIAsp.Net File</summary>

using System.ComponentModel;
using System.Globalization;
using System.Text;
using System.Web.UI;
using YUIAspNet.Common;

#region Embedded resources definitions
[assembly: WebResource("YUIAspNet.LayoutManager.LayoutManager.js", "text/javascript")]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.LayoutManager.layout.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.LayoutManager.container.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.LayoutManager.resize.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.LayoutManager.layout_sprite.png", "image/png")]

#endregion

namespace YUIAspNet
{
    /// <summary>
    /// LayoutManager control - complex layouts made simple.
    /// </summary>
    [ToolboxItem(true)]
    [ParseChildren(true)]
    public class LayoutManager : YUIScriptBaseControl, INamingContainer
    {
        private LayoutManagerContainer _container;

        /// <summary>
        /// Initializes a new instance of the <see cref="LayoutManager"/> class.
        /// </summary>
        public LayoutManager() : base("div")
        {
           _container = new LayoutManagerContainer();
        }

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            _container.CssClass = "container";
            _container.Style.Add("position", "relative");

            this.Controls.Add(_container);

            base.CreateChildControls();
        }

        /// <summary>
        /// Registers the style sheets for the current control.
        /// Must be overriden in the parent control to add any css file reference.
        /// </summary>
        protected override void RegisterStyleSheets()
        {
            RegisterEmbeddedStylesheet("LayoutManager", "container.css");
            RegisterEmbeddedStylesheet("LayoutManager", "resize.css");
            RegisterEmbeddedStylesheet("LayoutManager", "layout.css");
        }

        /// <summary>
        /// Register the values to send to the client control for initialization.
        /// </summary>
        protected override void RegisterClientInitialization() 
        {
            AddProperty("ContainerID", _container.ClientID);
            
            AddProperty("Height", Height);
            AddProperty("MinHeight", MinHeight);

            AddProperty("Width", Width);
            AddProperty("MinWidth", MinWidth);

            AddProperty("Units", BuildLayoutUnits(), true);
        }

        /// <summary>
        /// Builds the layout units.
        /// </summary>
        /// <returns></returns>
        private StringBuilder BuildLayoutUnits()
        {
            StringBuilder sb = new StringBuilder();

            foreach (LayoutUnit unit in LayoutUnits)
            {
                sb.AppendFormat(CultureInfo.InvariantCulture, "{0}{{", sb.Length > 0 ? "," : "");

                //always add position, to solve the ',' problem.
                sb.AppendFormat(CultureInfo.InvariantCulture, "position: '{0}'", unit.Position.ToString().ToLowerInvariant());

                if(unit.Animate)
                    sb.Append(", animate: true");

                if (unit.Close)
                    sb.Append(", close: true");

                if (unit.Collapse)
                    sb.Append(", collapse: true");

                if (unit.Resize)
                    sb.Append(", resize: true");

                if (unit.Scroll.HasValue)
                    sb.Append(", scroll: ").Append(unit.Scroll.ToString().ToLowerInvariant());
                else
                    sb.Append(", scroll: null");

                if (unit.CollapseSize > 0)
                    sb.AppendFormat(CultureInfo.InvariantCulture, ", collapseSize: {0}", unit.CollapseSize);

                if(unit.DataUrl != null)
                    sb.Append(", dataUrl: ").Append(unit.DataUrl);

                if(unit.Height > 0)
                    sb.Append(", height: ").Append(unit.Height);

                if(unit.MaxHeight > 0)
                    sb.Append(", maxHeight: ").Append(unit.MaxHeight);

                if (unit.MinHeight > 0)
                    sb.Append(", minHeight: ").Append(unit.MinHeight);

                if (unit.Width > 0)
                    sb.Append(", width: ").Append(unit.Width);

                if (unit.MaxWidth > 0)
                    sb.Append(", maxWidth: ").Append(unit.MaxWidth);

                if (unit.MinWidth > 0)
                    sb.Append(", minWidth: ").Append(unit.MinWidth);

                if(unit.ZIndex > 0)
                    sb.Append(", zIndex: ").Append(unit.ZIndex);

                if (unit.Header.Parent != null)
                    sb.AppendFormat(CultureInfo.InvariantCulture, ", header: $get('{0}').innerHTML", unit.Header.ClientID);

                if (unit.Content.Parent != null)
                    sb.AppendFormat(CultureInfo.InvariantCulture, ", body: '{0}'", unit.Content.ClientID);

                if (unit.Footer.Parent != null)
                    sb.AppendFormat(CultureInfo.InvariantCulture, ", footer: '{0}'", unit.Footer.ClientID);

                sb.Append("}");
            }

            sb.Append("]");
            sb.Insert(0, "[");
            return sb;
        }

        /// <summary>
        /// Registers any additional scripts to include for this control.
        /// </summary>
        protected override void RegisterScriptReferences()
        {
            AddScriptReference(new ScriptReference("YUIAspNet.LayoutManager.LayoutManager.js", this.GetType().Assembly.FullName));
        }

        /// <summary>
        /// Creates a new <see cref="T:System.Web.UI.ControlCollection"/> object to hold the child controls (both literal and server) of the server control.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Web.UI.ControlCollection"/> object to contain the current server control's child server controls.
        /// </returns>
        protected override ControlCollection CreateControlCollection()
        {
            base.CreateControlCollection();

            return new ControlCollection(this);
        }

        #region Public properties
        /// <summary>
        /// Gets the layout units.
        /// </summary>
        /// <value>The layout units.</value>
        [Category("Data"), Description("Layout units.")]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public LayoutUnitCollection LayoutUnits
        {
            get { return (LayoutUnitCollection)_container.Controls; }
        }

        /// <summary>
        /// Gets or sets the height of the Web server control.
        /// </summary>
        /// <value></value>
        /// <returns>A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the height of the control. The default is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>.</returns>
        /// <exception cref="T:System.ArgumentException">The height was set to a negative value.</exception>
        public new int Height { get; set; }
        /// <summary>
        /// Gets or sets the height of the min.
        /// </summary>
        /// <value>The height of the min.</value>
        public int MinHeight { get; set; }

        /// <summary>
        /// Gets or sets the width of the Web server control.
        /// </summary>
        /// <value></value>
        /// <returns>A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the width of the control. The default is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>.</returns>
        /// <exception cref="T:System.ArgumentException">The width of the Web server control was set to a negative value. </exception>
        public new int Width { get; set; }
        /// <summary>
        /// Gets or sets the width of the min.
        /// </summary>
        /// <value>The width of the min.</value>
        public int MinWidth { get; set; } 
        #endregion
    }
}
